package org.dyndns.opendemogroup.optimizer.problems;

import static org.junit.Assert.assertEquals;

import java.beans.XMLDecoder;
import java.io.ByteArrayInputStream;

import org.dyndns.opendemogroup.optimizer.Member;
import org.junit.Test;

/**
 * A class to test the class TravellingSalesmanProblem
 */
public class TravellingSalesmanProblemTest
{

	/**
	 * Tests the <i>distance</i> method with a typical scenario: pythagoras'
	 * triangle: 3, 4, 5
	 */
	@Test
	public void distance_Typical ( )
	{
		double xi = 0.0;
		double yi = 0.0;
		double xj = 3.0;
		double yj = 4.0;
		long actual =
			TravellingSalesmanProblem.computeDistance ( xi, yi, xj, yj );
		long expected = 5L;
		assertEquals ( expected, actual );
	}

	/**
	 * Tests the <i>computeFitness</i> method with a typical scenario:
	 * pythagoras' triangle with sides of length: 3, 4 and 5. This is done by
	 * constructing an instance of the {@link TravellingSalesmanProblem} class
	 * directly.
	 */
	@Test
	public void computeFitness_PythagorasDirectConstruction ( )
	{
		final double[][] cities = new double[][]
		{
			{
				1, 0.0, 0.0
			},
			{
				2, 3.0, 0.0
			},
			{
				3, 3.0, 4.0
			},
		};
		TravellingSalesmanProblem tsp = new TravellingSalesmanProblem ( cities );

		checkPythagoras ( tsp );
	}

	private void checkPythagoras ( TravellingSalesmanProblem tsp )
	{
		// { set-up
		Member source = new Member ( tsp.getMemberSize ( ) );
		for ( int i = 0; i < tsp.getMemberSize ( ); i++ )
		{
			source.genome[i] = i;
		}
		tsp.decodeFrom ( source );
		// }

		double actual = tsp.computeFitness ( null );
		double expected = 3 + 4 + 5;
		assertEquals ( expected, actual );
	}

	/**
	 * Tests the <i>computeFitness</i> method with a typical scenario:
	 * pythagoras' triangle with sides of length: 3, 4 and 5. This is done by
	 * constructing an instance of the {@link TravellingSalesmanProblem} class
	 * by deserializing it from an XML string using Java's persistence API.
	 */
	@Test
	public void computeFitness_PythagorasDeserializedConstruction ( )
	{
		String input =
			"<java version=\"1.6.0_03\" class=\"java.beans.XMLDecoder\">"
					+ "<object class=\"org.dyndns.opendemogroup.optimizer.problems.TravellingSalesmanProblem\">"
					+ "<array class=\"[D\">"
					+ "<array class=\"double\">"
					+ "<double>1</double><double>0.0</double><double>0.0</double>"
					+ "</array>"
					+ "<array class=\"double\">"
					+ "<double>2</double><double>3.0</double><double>0.0</double>"
					+ "</array>"
					+ "<array class=\"double\">"
					+ "<double>3</double><double>3.0</double><double>4.0</double>"
					+ "</array>" + "</array>" + "</object>" + "</java>";
		byte[] bytes = input.getBytes ( );
		ByteArrayInputStream bais = new ByteArrayInputStream ( bytes );
		XMLDecoder decoder = new XMLDecoder ( bais );
		TravellingSalesmanProblem tsp =
			(TravellingSalesmanProblem) decoder.readObject ( );
		checkPythagoras ( tsp );
	}

}
